/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package it.trick.admin.controller;

import it.trick.admin.App;
import it.trick.admin.Util;
import it.trick.admin.model.PageModel;
import it.trick.admin.model.PreModel;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.WorkerStateEvent;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.MenuItem;
import javafx.scene.control.SplitPane;
import javafx.scene.control.TextArea;
import javafx.scene.control.Toggle;
import javafx.scene.control.ToggleGroup;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.KeyCombination;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.web.WebView;

/**
 * FXML Controller class
 *
 * @author takahara
 */
public class EditPageViewController extends AnchorPane implements Initializable {

    private static EditPageViewController instance;

    @FXML
    private TextArea contentsTextArea;
    @FXML
    private BorderPane editMainBorderPane;
    @FXML
    private TextArea descriptionTextArea;
    @FXML
    private TextArea keywordListTextArea;
    @FXML
    public ListView<PreModel> preListView;
    @FXML
    public HBox progressIndicatorHBox;
    @FXML
    private Label contentNameLabel;
    @FXML
    private WebView contentWebView;
    @FXML
    private ToggleGroup myToggleGroup;
    @FXML
    private SplitPane editView;

    private PageModel pageModel;
    private EventHandler preservationEventHandler;


    /**
     * コンストラクタ
     */
    public EditPageViewController(PageModel pageModel) {
        this.pageModel = pageModel;
        init();
    }

    /**
     * コントロールの初期化
     */
    private void init() {

        // ---------------------------------------------------
        // FXMLのロードと設定
        // ---------------------------------------------------
        FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource("resource/fxml/edit_page_view.fxml"));
        fxmlLoader.setRoot(this);
        // 自分自身をコントロールとして設定
        fxmlLoader.setController(this);

        try {
            fxmlLoader.load();
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }

        instance = this;
    }

    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {

        // ToggleGroupの設定
        myToggleGroup.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
            @Override
            public void changed(ObservableValue<? extends Toggle> ov,
                    Toggle toggle, Toggle new_toggle) {

                if (new_toggle == null) {
                    editView.setVisible(false);
                    contentWebView.setVisible(true);
                    setupWebView();

                } else if (myToggleGroup.getSelectedToggle().getUserData().equals("view")) {
                    editView.setVisible(false);
                    contentWebView.setVisible(true);
                    setupWebView();
                } else {
                    editView.setVisible(true);
                    contentWebView.setVisible(false);
                    setupEditView();
                }
            }
        });

        // コンテンツタイトルの設定
        contentNameLabel.setText(pageModel.getName()
                + "          (" + pageModel.getPrarentKeyString() + "/" + pageModel.getKeyValueString() + ")");

        // webviewの初期化
        String urlString = App.getInstance().getSite() + "client/view/page?page=" + pageModel.getKeyValueString();
        progressIndicatorHBox.visibleProperty().bind(contentWebView.getEngine().getLoadWorker().runningProperty());
        contentWebView.getEngine().load(urlString);

        // 保存イベントの設定
        preservationEventHandler = new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent t) {
                if(KeyCombination.keyCombination("Shortcut+S").match(t)) {
                    preservationAction();
                }
            }
        };

    }

    /**
     * webview の設定
     */
    private void setupWebView() {
        contentWebView.getEngine().reload();

        // 保存キーコンビネーションイベント
        editMainBorderPane.removeEventHandler(KeyEvent.KEY_RELEASED, preservationEventHandler);
    }

    /**
     * 編集ビューの設定
     */
    private void setupEditView() {

        // Description
        if(pageModel.getDescription() == null) pageModel.setDescription("");
        descriptionTextArea.setText(pageModel.getDescription());

        // Content
        contentsTextArea.setText(pageModel.getContent());

        // keyWord
        String keyWord = Util.keywordListToString(pageModel.getKeyWordList());
        if (keyWord != null) {
            keywordListTextArea.setText(keyWord);
        }else {
            keywordListTextArea.setText("");
        }

        // ソースリストビューのロード
        loadPreListView();

        // 保存キーコンビネーションイベント
        editMainBorderPane.addEventHandler(KeyEvent.KEY_RELEASED, preservationEventHandler);

        // preからのドロップイベントの設定
        setDropEvent();

        // コンテキストメニューの設定
        setContextMenu();
    }

    /**
     * ソースリストビューのロード
     */
    public void loadPreListView() {
        // preListView
        ChannelTopController.getInstance().loadPreListTask.setup(pageModel);
        ChannelTopController.getInstance().loadPreListTask.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
            @Override
            public void handle(WorkerStateEvent t) {

                // サービスの処理結果を受け取る
                List<PreModel> listItems = (List<PreModel>) t.getSource().getValue();

                // Tree Root Nodeを設定する
                preListView.getItems().setAll(listItems);
            }
        });
        ChannelTopController.getInstance().loadPreListTask.restart();
    }

    @FXML
    public void addPreAction() {
        AddPreViewController addController = new AddPreViewController(pageModel);
        App.getInstance().showPopStage(addController, "ソース追加", 600, 600, false);
    }



    /**
     * 保存アクション
     */
    private void preservationAction() {

        pageModel.setDescription(descriptionTextArea.getText());
        pageModel.setContent(contentsTextArea.getText());
        pageModel.setKeyWordList(Util.keywordStringToList(keywordListTextArea.getText()));

        ChannelTopController.getInstance().updatePageTask.setup(pageModel);
        ChannelTopController.getInstance().updatePageTask.restart();
    }

    /**
     * ドロップイベントの設定
     */
    private void setDropEvent() {
        // ---------------------------------------------------------------------
        // ドラッグ中
        // ---------------------------------------------------------------------
        contentsTextArea.setOnDragOver(
                new EventHandler<DragEvent>() {
            @Override
            public void handle(DragEvent event) {
                event.acceptTransferModes(TransferMode.COPY);
            }
        });

        // ---------------------------------------------------------------------
        // ドラッグ実行
        // ---------------------------------------------------------------------
        contentsTextArea.setOnDragDropped(
                new EventHandler<DragEvent>() {
            @Override
            public void handle(DragEvent t) {

                // ドラッグボードからカテゴリパスを取得
                Dragboard db = t.getDragboard();
                if (db.hasString()) {
                    String preKeyString = db.getString();

                    String tmp = contentsTextArea.getText();
                    contentsTextArea.setText(tmp + preKeyString);
                }
            }
        });
    }

    /**
     * コンテキストメニューの設定
     */
    private void setContextMenu() {
        ContextMenu contextMenu = new ContextMenu();
        MenuItem H2TagMenuItem = new MenuItem("<h2>");
        MenuItem PTagMenuItem = new MenuItem("<p>");

        contextMenu.getItems().addAll(
                H2TagMenuItem,
                PTagMenuItem);

        H2TagMenuItem.addEventHandler(ActionEvent.ACTION, new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent t) {
                String selectedText = contentsTextArea.getSelectedText();
                String tmp = contentsTextArea.getText();
                String newString = tmp.replaceAll(selectedText, "<h2>" + selectedText + "</h2>");
                contentsTextArea.setText(newString);
            }
        });

        PTagMenuItem.addEventHandler(ActionEvent.ACTION, new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent t) {
                String selectedText = contentsTextArea.getSelectedText();
                String tmp = contentsTextArea.getText();
                String newString = tmp.replaceAll(selectedText, "<p>" + selectedText + "</p>");
                contentsTextArea.setText(newString);
            }
        });

        contentsTextArea.setContextMenu(contextMenu);
        contentsTextArea.setOnMouseClicked(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent t) {
                    // コンテキストメニュー表示イベント
                    if (t.isControlDown()) {
                        contentsTextArea.getContextMenu().show(contentsTextArea, t.getScreenX(), t.getScreenY());
                    }
                }
            });
    }

    /**
     * Get App Instance
     *
     * @return
     */
    public static EditPageViewController getInstance() {
        return instance;
    }
}
